package com.motu.monstercity.server.game.logic;

import com.motu.monstercity.module.common.iap.Iap;
import com.motu.monstercity.module.common.iap.IapGift;
import com.motu.monstercity.module.common.iap.IapGiftPush;
import com.motu.monstercity.module.common.iap.IapProduct;
import com.motu.monstercity.server.game.base.AllParam;
import com.motu.monstercity.server.game.commondata.iap.GrowthFund;
import com.motu.monstercity.server.game.commondata.iap.IapDiamond;
import com.motu.monstercity.server.game.commondata.iap.PrivilegeCard;
import com.motu.monstercity.server.game.commondata.iap.Vip;
import com.motu.vertx.module.utility.mysql.MysqlClient;
import com.motu.vertx.module.utility.mysql.MysqlTool;
import com.motu.vertx.module.utility.toolset.Tool;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

public class IapBaseData {
    public final static Logger logger = LoggerFactory.getLogger(IapBaseData.class);

    private static ConcurrentHashMap<Integer, Iap> iapMap = new ConcurrentHashMap<>();
    private static ConcurrentHashMap<Integer, IapGift> iapGiftMap = new ConcurrentHashMap<>();// iap礼包
    private static ConcurrentHashMap<Integer, List<IapGift>> iapGiftTypeMap = new ConcurrentHashMap<>();// iap礼包类型列表
    private static ConcurrentHashMap<String, IapProduct> iapProductMap = new ConcurrentHashMap<>();
    private static ConcurrentHashMap<Integer, IapGiftPush> iapGiftPushMap = new ConcurrentHashMap<>(); // 推送礼包配置表
    private static ConcurrentHashMap<Integer, List<IapGiftPush>> iapGiftPushListMap = new ConcurrentHashMap<>();
   // private static ConcurrentHashMap<Integer, List<IapGiftPush>> iapGiftPushMapOfRepeat = new ConcurrentHashMap<>();
    private static ConcurrentHashMap<Integer, ConcurrentHashMap<Integer, ConcurrentHashMap<Long, GrowthFund>>> growthFundMap = new ConcurrentHashMap<>(); // 成长基金配置表 <type.groupId.num>
    private static ConcurrentHashMap<Integer, PrivilegeCard> privilegeCardMap = new ConcurrentHashMap<>(); // 特权卡表
    private static ConcurrentHashMap<Integer, List<IapDiamond>> iapDiamondMap = new ConcurrentHashMap<>();
    private static Vip[] vipList = new Vip[AllParam.VIP_MAX + 1];
    private static ConcurrentHashMap<Integer, Vip> vipLevelMap = new ConcurrentHashMap<>(); // vip等级表<levele,vip>

    // 公共数据初始化
    public static void init(List<Future> futures) {
        futures.add(initIapGift());
        futures.add(initIap());
        futures.add(initIapProduct());
        futures.add(initIapGiftPush());
        futures.add(initGrowthFund());
        futures.add(initPrivilegeCard());
        futures.add(initIapDiamond());
        futures.add(initVip());
    }


    /**
     * 初始化推送礼包配置表
     */
    public static Future<Void> initIapGiftPush() {
        String table = "iap_gift_push";
        Promise promise = Promise.promise();
        String sql = "select * from " + table + ";";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getCommonPool(), sql, new JsonArray(), res -> {
            if (res.succeeded()) {
                try {
                    ConcurrentHashMap<Integer, IapGiftPush> tmp = new ConcurrentHashMap<>();
                    ConcurrentHashMap<Integer, List<IapGiftPush>> tmp1 = new ConcurrentHashMap<>();
//                    ConcurrentHashMap<Integer, List<IapGiftPush>> tmp3 = new ConcurrentHashMap<>();
                    JsonArray result = res.result();
                    logger.info("init " + table + " size:" + result.size());
                    for (int i = 0; i < result.size(); i++) {
                        IapGiftPush entity = new IapGiftPush(result.getJsonObject(i));
                        tmp.put(entity.getIapGiftId(), entity);
                        if (!tmp1.containsKey(entity.getType())) {
                            List<IapGiftPush> tmp2 = new ArrayList<>();
                            tmp1.put(entity.getType(), tmp2);
                        }
                        List<IapGiftPush> tmp2 = tmp1.get(entity.getType());
                        tmp2.add(entity);
//                        if (entity.getRepeatType() > 0) {
//                            if (!tmp3.containsKey(entity.getRepeatType())) {
//                                List<IapGiftPush> tmp4 = new ArrayList<>();
//                                tmp3.put(entity.getRepeatType(), tmp4);
//                            }
//                            List<IapGiftPush> tmp4 = tmp3.get(entity.getRepeatType());
//                            tmp4.add(entity);
//                        }
                    }
                    iapGiftPushMap = tmp;
                    iapGiftPushListMap.clear();
                    iapGiftPushListMap = tmp1;
                    promise.complete();
                } catch (Exception e) {
                    logger.error("init " + table + " error exception:" + Tool.getException(e));
                    promise.fail(e);
                }
            } else {
                logger.error(res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }

    public static IapGiftPush getIapGiftPush(int id) {
        IapGiftPush result = iapGiftPushMap.get(id);
        if (result == null) {
            logger.error("getIapGiftPush error key = " + id);
        }
        return result;
    }
    public static ConcurrentHashMap<Integer, IapGiftPush> getIapGiftPushMap() { return iapGiftPushMap; }

    public static List<IapGiftPush> getIapGiftPushList(int type) {
        return iapGiftPushListMap.get(type);
    }

    // 获取指定类型的主礼包
    public static List<IapGiftPush> getIapGiftPushMainList(int type) {
        List<IapGiftPush> result = new ArrayList<>();
        List<IapGiftPush> list = iapGiftPushListMap.get(type);
        if (list == null) {
            return result;
        }
        result = list.stream().filter(g -> g.getMainIapGiftId() == g.getIapGiftId()).toList();
        return result;
    }

//    public static List<IapGiftPush> getRepeatIapGiftPushList(int repeatType) {
//        return iapGiftPushMapOfRepeat.get(repeatType);
//    }

    /***
     * 初始化iap列表
     * @return
     */
    public static Future<Void> initIap() {
        Promise promise = Promise.promise();
        String sql = "select * from iap;";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getCommonPool(), sql, new JsonArray(), res -> {
            if (res.succeeded()) {
                ConcurrentHashMap<Integer, Iap> tmp = new ConcurrentHashMap<>();
                JsonArray list = res.result();
                logger.info("initIap size:" + list.size());
                for (int i = 0; i < list.size(); i++) {
                    Iap iap = new Iap(list.getJsonObject(i));
                    tmp.put(iap.getId(), iap);
                }
                iapMap.clear();
                iapMap = tmp;
                promise.complete();
            } else {
                logger.error(res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }

    /****
     * 根据iapid获取iap项
     * @param key iapid
     * @return
     */
    public static Iap getIap(int key) {
        if (iapMap.containsKey(key)) {
            return iapMap.get(key);
        } else {
            logger.error("getIap error key:" + key);
            return null;
        }
    }

    /***
     * 初始化iapProduct列表
     * @return
     */
    public static Future<Void> initIapProduct() {
        logger.info("initIapProduct !!!");
        Promise promise = Promise.promise();
        String sql = "select * from iap_product;";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getCommonPool(), sql, new JsonArray(), res -> {
            if (res.succeeded()) {
                ConcurrentHashMap<String, IapProduct> tmp = new ConcurrentHashMap<>();
                JsonArray list = res.result();
                logger.info("initIapProduct size:" + list.size());
                for (int i = 0; i < list.size(); i++) {
                    IapProduct iapproduct = new IapProduct(list.getJsonObject(i));
                    tmp.put(iapproduct.getProductId(), iapproduct);
                }
                iapProductMap.clear();
                iapProductMap = tmp;
                promise.complete();
            } else {
                logger.error("initIapproduct error:" + res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }

    /****
     * 根据key获取iapProduct项
     * @param key iapProductId
     * @return
     */
    public static IapProduct getIapProduct(String key) {
        if (iapProductMap.containsKey(key)) {
            return iapProductMap.get(key);
        } else {
            logger.error("getIapProduct error key:" + key);
            return null;
        }
    }

    public static List<IapProduct> getIapProductByPackage(String packageName) {
        List<IapProduct> list = new ArrayList<>();
        for (IapProduct iapProduct : iapProductMap.values()) {
            if (iapProduct.getPackageName().equalsIgnoreCase(packageName)) {
                list.add(iapProduct);
            }
        }
        return list;
    }


    public static String getIapProductId(String packageName, int iapId) {
        for (IapProduct iapProduct : iapProductMap.values()) {
            if (iapProduct.getPackageName().equalsIgnoreCase(packageName)
                    && iapId == iapProduct.getIapId()) {
                return iapProduct.getProductId();
            }
        }
        logger.error("getIapProductId packageName:" + packageName + ", ipdId:" + iapId);
        return null;
    }

    /***
     * 判断是否为有效的产品Id
     * @param iapId 产品项Id
     * @param productId 产品id
     */
    public static boolean checkAppProductId(int iapId, String productId) {
        for (IapProduct iapProduct : iapProductMap.values()) {
            if (iapProduct.getIapId() == iapId
                    && iapProduct.getProductId().equalsIgnoreCase(productId)) {
                return true;
            }
        }
        return false;
    }



    public static Future<Void> initIapGift() {
        Promise promise = Promise.promise();
        String sql = "select * from iap_gift;";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getCommonPool(), sql, new JsonArray(), res -> {
            if (res.succeeded()) {
                ConcurrentHashMap<Integer, IapGift> tmp = new ConcurrentHashMap<>();
                ConcurrentHashMap<Integer, List<IapGift>> typeTmp = new ConcurrentHashMap<>();

                JsonArray list = res.result();
                logger.info("initIapGift size:" + list.size());
                for (int i = 0; i < list.size(); i++) {
                    IapGift iap = new IapGift(list.getJsonObject(i));
                    tmp.put(iap.getId(), iap);

                    int type = iap.getType();
                    List<IapGift> tmpList = new ArrayList<>();
                    if (typeTmp.containsKey(type)) {
                        tmpList = typeTmp.get(type);
                        typeTmp.put(type, tmpList);
                    }
                    tmpList.add(iap);
                    typeTmp.put(type, tmpList);
                }
                iapGiftMap = tmp;
                iapGiftTypeMap = typeTmp;
                promise.complete();
            } else {
                logger.error(res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }

    public static IapGift getIapGift(int key) {
        if (iapGiftMap.containsKey(key)) {
            return iapGiftMap.get(key);
        } else {
            logger.error("getIapGift error key:" + key);
            return null;
        }
    }

    public static List<IapGift> getIapGiftTypeList(int type) {
        if (iapGiftTypeMap.containsKey(type)) {
            return iapGiftTypeMap.get(type);
        } else {
            logger.error("getIapGiftTypeList error type:" + type);
            return new ArrayList<>();
        }
    }


    /**
     * 初始化成长基金配置表
     */
    public static Future<Void> initGrowthFund() {
        String table = "growth_fund";
        Promise promise = Promise.promise();
        String sql = "select * from " + table + ";";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getCommonPool(), sql, new JsonArray(), res -> {
            if (res.succeeded()) {
                try {
                    //<type, <groupId, <level,GrowthFund>>>
                    ConcurrentHashMap<Integer, ConcurrentHashMap<Integer, ConcurrentHashMap<Long, GrowthFund>>> typeMap = new ConcurrentHashMap<>();//基金类型map
                    JsonArray result = res.result();
                    logger.info("init " + table + " size:" + result.size());
                    for (int i = 0; i < result.size(); i++) {
                        GrowthFund entity = new GrowthFund(result.getJsonObject(i));
                        int type = entity.getType();
                        int groupId = entity.getGroupId();
                        long num = entity.getNum();
                        ConcurrentHashMap<Integer, ConcurrentHashMap<Long, GrowthFund>> groupIdMap = new ConcurrentHashMap<>();//基金档次map
                        if (typeMap.containsKey(type)) {
                            groupIdMap = typeMap.get(type);
                        }
                        ConcurrentHashMap<Long, GrowthFund> numMap = new ConcurrentHashMap<>();//基金条件map
                        if (groupIdMap.containsKey(groupId)) {
                            numMap = groupIdMap.get(groupId);
                        }
                        numMap.put(num, entity);
                        groupIdMap.put(groupId, numMap);
                        typeMap.put(type, groupIdMap);
                    }
                    growthFundMap = typeMap;
                    promise.complete();
                } catch (Exception e) {
                    logger.error("init " + table + " error exception:" + Tool.getException(e));
                    promise.fail(e);
                }
            } else {
                logger.error(res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }


    public static ConcurrentHashMap<Integer, ConcurrentHashMap<Integer, ConcurrentHashMap<Long, GrowthFund>>> getGrowthFundMap() { return growthFundMap; }

    public static ConcurrentHashMap<Long, GrowthFund> getGrowthFundGroupMap(int type ,int groupId) {
        return growthFundMap.get(type).get(groupId);
    }

    public static GrowthFund getGrowthFund(int type ,int groupId,long num) {
        GrowthFund result = growthFundMap.get(type).get(groupId).get(num);
        if (result == null) {
            logger.error("getGrowthFund error type = " + type + " groupId = " + groupId + " num = " + num);
        }
        return result;
    }

    /**
     * 获取成长基金的分组id
     */
    public static int getGrowthFundGroupId(int[] growthFundGroups,int iapGiftId) {
        for (int i = 0; i < growthFundGroups.length; i++) {
            if (growthFundGroups[i] == iapGiftId) {
                return i + 1;
            }
        }
        return -1;
    }

    /**
     * 初始化特权卡表
     */
    public static Future<Void> initPrivilegeCard() {
        String table = "privilege_card";
        Promise promise = Promise.promise();
        String sql = "select * from " + table + ";";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getCommonPool(), sql, new JsonArray(), res -> {
            if (res.succeeded()) {
                try {
                    ConcurrentHashMap<Integer, PrivilegeCard> tmp = new ConcurrentHashMap<>();
                    JsonArray result = res.result();
                    logger.info("init " + table + " size:" + result.size());
                    for (int i = 0; i < result.size(); i++) {
                        PrivilegeCard entity = new PrivilegeCard(result.getJsonObject(i));
                        tmp.put(entity.getId(), entity);
                    }
                    privilegeCardMap = tmp;
                    promise.complete();
                } catch (Exception e) {
                    logger.error("init " + table + " error exception:" + Tool.getException(e));
                    promise.fail(e);
                }
            } else {
                logger.error(res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }

    public static PrivilegeCard getPrivilegeCard(int id) {
        PrivilegeCard result = privilegeCardMap.get(id);
        if (result == null) {
            logger.error("getPrivilegeCard error key = " + id);
        }
        return result;
    }
    public static PrivilegeCard getPrivilegeCardByIapGfitId(int iapGiftId) {
        for (PrivilegeCard card : privilegeCardMap.values()) {
            if (card.getIapGiftId() == iapGiftId) {
                return card;
            }
        }
        logger.error("getPrivilegeCard error iapGiftId = " + iapGiftId);
        return null;
    }
    public static ConcurrentHashMap<Integer, PrivilegeCard> getPrivilegeCardMap() { return privilegeCardMap; }

    /**
     * 初始化iap礼包额外获得钻石配置表
     */
    public static Future<Void> initIapDiamond() {
        String table = "iap_diamond";
        Promise promise = Promise.promise();
        String sql = "select * from " + table + ";";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getCommonPool(), sql, new JsonArray(), res -> {
            if (res.succeeded()) {
                try {
                    ConcurrentHashMap<Integer, List<IapDiamond>> tmp = new ConcurrentHashMap<>();
                    JsonArray result = res.result();
                    logger.info("init " + table + " size:" + result.size());
                    for (int i = 0; i < result.size(); i++) {
                        IapDiamond entity = new IapDiamond(result.getJsonObject(i));
                        List<IapDiamond> list = tmp.get(entity.getIapGift());
                        if (list == null) {
                            list = new ArrayList<>();
                            tmp.put(entity.getIapGift(), list);
                        }
                        list.add(entity);
                    }
                    iapDiamondMap = tmp;
                    promise.complete();
                } catch (Exception e) {
                    logger.error("init " + table + " error exception:" + Tool.getException(e));
                    promise.fail(e);
                }
            } else {
                logger.error(res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }

    public static List<IapDiamond> getIapDiamondList(int iapId) {
        List<IapDiamond> result = iapDiamondMap.get(iapId);
        if (result == null) {
            logger.error("getIapDiamond error iapId = " + iapId);
        }
        return result;
    }

    /**
     * 初始化vip等级表
     * 不可直接覆盖
     */
    public static Future<Void> initVip() {
        String table = "vip";
        Promise promise = Promise.promise();
        String sql = "select * from " + table + ";";
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getCommonPool(), sql, new JsonArray(), res -> {
            if (res.succeeded()) {
                try {
                    JsonArray list = res.result();
                    logger.info("initVip size:" + list.size());
                    for (int i = 0, size = list.size(); i < size; i++) {
                        JsonObject obj = list.getJsonObject(i);
                        Vip vip = new Vip(obj);
                        vipList[vip.getLevel()] = vip;
                    }
                    promise.complete();
                } catch (Exception e) {
                    logger.error("init " + table + " error exception:" + Tool.getException(e));
                    promise.fail(e);
                }

            } else {
                logger.error(res.cause().getMessage());
                promise.fail(res.cause());
            }
        });
        return promise.future();
    }

    public static Vip[] getVipList() {
        return vipList;
    }

    public static Vip getVipByLv(int vip) {
        return vipList[vip];
    }
}
